package edu.luc.concordia;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
/**
 * Copyright 2008 Project Concordia
 * <p>
 * This file is part of RetailReturnSystem.
 * <p>
 * RetailReturnSystem is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * <p>
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * <p>
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.
 * <hr>
 * Read the receipt and return receipt file and generate Report 
 * @author Piyusha Desai
 * @version 1.0 2008-11-22
 * 
 */

public class ReportGenerator 
{    
	//Variable Declaration
	private ArrayList<Receipt> myReceiptItems = new ArrayList();
    private ArrayList<String> myReport= new ArrayList() ;
    
    //Class Constructor , Initializes variable and read XML file
    public ReportGenerator(ArrayList<Receipt> items) 
    {
    myReceiptItems = items;
    try
    {
    	//XML file reader to read receipt file	
    	XMLReader xr = XMLReaderFactory.createXMLReader();
    	XMLReader xs = XMLReaderFactory.createXMLReader();
    	SAXCounter saxc = new SAXCounter();
    	saxCounter saxC = new saxCounter();
    	xr.setContentHandler( saxc );
    	xs.setContentHandler(saxC);
    	xr.parse( new InputSource(new FileReader( "receipt.xml" )) );
    	xs.parse(new InputSource(new FileReader("returns.xml")));
    }
    catch( Exception e ) 
    {
    	 e.printStackTrace();
    }
    }
    
    /**
     * This method will determine total sale, total purchase items, total return items,
     * total refund and total fraud for report.
     */
    private void calculateReportValues()
    {
    	double totalSales = 0.0;
    	double totalPurchaseItems = 0.0;
    	double totalReturnItems=0.0;
    	double totalRefund =0.0;
    	double totalFraud =0.0;
    	    	  
    }
    /**
     * Write the report information in report file
     */
    private void updateReportFile()
    {
    	FileWriter writer = null;
    	double subTotal = 0.0;
    	double tax = 0.0;
    	double total = 0.0;
    	
    	//Creating an empty XML Document
    		DocumentBuilderFactory dbfac =  DocumentBuilderFactory.newInstance();
    		DocumentBuilder docBuilder = null;
    		try {
    			docBuilder = dbfac.newDocumentBuilder();
    			
    		} 
    		catch (ParserConfigurationException e) 
    		{
    			e.printStackTrace();
    		}
    		Document doc = docBuilder.newDocument();

    		//Creating the XML tree
    		//create the root element and add it to the document
    		Element root = doc.createElement("Report");
    		doc.appendChild(root);
    		
    		try {
    			writer = new FileWriter("report.xml", true);
    		} catch (IOException e1) {
    			e1.printStackTrace();
    		}
    		for (int i = 0; i < myReceiptItems.size(); i++){

    			Receipt templist = myReceiptItems.get(i);
                    			
    			String totalSale = " ";
    			
    			Element child1 = doc.createElement("totalSale");
    			root.appendChild(child1);    		
    			Text text1 = doc.createTextNode(totalSale);
    			child1.appendChild(text1);

    		
    			String totalPurchaseItems = " " ;
    		 	Element child2 = doc.createElement("totalPurchaseItems");
    			root.appendChild(child2);    			
    			Text text2 = doc.createTextNode(totalPurchaseItems);
    			child2.appendChild(text2);
    			
    			    		
    			String totalReturnItems = " ";    			
    			Element child4 = doc.createElement("totalReturnItems");
    			root.appendChild(child4);    			
    			Text text4 = doc.createTextNode(totalReturnItems);
    			child4.appendChild(text4);

    			
    			String totalRefund = " ";    		
    			Element child5 = doc.createElement("totalRefund");
    			root.appendChild(child5);    			
    			Text text5 = doc.createTextNode(totalRefund);
    			child5.appendChild(text5);
    			
    		
    			String totalFraud = " ";    			
    			Element child6 = doc.createElement("totalFraud");
    			root.appendChild(child6);    			
    			Text text6 = doc.createTextNode(totalFraud);
    			child6.appendChild(text6);

    			//Output the XML
    			//set up a transformer
    			TransformerFactory transfac = TransformerFactory.newInstance();
    			Transformer trans = null;
    			try 
    			{
    				trans = transfac.newTransformer();
    				
    			} catch (TransformerConfigurationException e) {
    				e.printStackTrace();
    			}
    			trans.setOutputProperty(OutputKeys.INDENT, "yes");

    			//create string from xml tree
    			StringWriter sw = new StringWriter();
    			StreamResult result = new StreamResult(sw);
    			DOMSource source = new DOMSource(doc);
    			try 
    			{
    				trans.transform(source, result);
    				
    			} catch (TransformerException e) {
    				e.printStackTrace();
    			}
    			String xmlString = sw.toString();
    			
    			//to display xml in myReceipt.xml and close it
    			try 
    			{		
    				writer.write(xmlString);
    				writer.flush();				
    			} 
    			catch (IOException e) 
    			{
    				e.printStackTrace();
    			}				
    		}
    		try 
    		{
    			writer.close();
    		} catch (IOException e) 
    		{
    			e.printStackTrace();
    		}	
    	
    }
    /**
     * Call the calculateReportValues() and updateReportFile() for generating report
     * @return items from myReport to display in Report
     */
    public ArrayList<String> generateReport() 
    {
 	  calculateReportValues();
 	  updateReportFile();
 	  return myReport;
    }
    /**
     * XML Parser for purchase receipt
     */
    private class SAXCounter extends DefaultHandler
    {
    	private HashMap<String, ReceiptInfo> receipts;
		private ReceiptInfo receiptInfo;
		private String contents; 
		
		/**
		 * Class constructor.
		 */
		public SAXCounter()
		{
			receipts = new HashMap<String, ReceiptInfo>();
			
		}
		/**
		 * Indication of first element of XML file
		 */
		public void startElement( String sname, String qname)
		throws SAXException 
		{
			String ename = sname; 
			if ("".equals(ename))
				ename = qname;
			if (ename.equals("finalReceipt")) 
			{ 
				receiptInfo = new ReceiptInfo();
			}			
		}
		/**
		 * All elements preceding first element in XML file
		 */
		public void endElement(String sName,String qName)
		throws SAXException {
			String eName = sName; 
			if ("".equals(eName))
				eName = qName; 
			if (eName.equals("finalReceipt")) 
			{ 
				receipts.put(receiptInfo.uid, receiptInfo);
			}// when the parser encounters </finalreceipt>,add the receiptInfo to hashmap
			if (eName.equals("uid")) 
			{
				receiptInfo.uid = contents;
			} // when the parser encounters </uid>,record uid
			if (eName.equals("description")) 
			{ 
				receiptInfo.description = contents;
			}// when the parser encounters </description>,record description
			if (eName.equals("subTotal")) 
			{ 
				receiptInfo.subTotal = contents;
			}// when the parser encounters </subTotal>,record subTotal
			if (eName.equals("total")) 
			{ 
				receiptInfo.total = contents;
			}// when the parser encounters </total>,record total
			
		}
        /**
         * Method for formatting
         */
        
		public void characters(char[] buf, int offset, int len)
				throws SAXException {
			contents = new String(buf, offset, len).trim();
		}
		
		}
    /**
     * XML Parser for return receipt
     */
    private class saxCounter extends DefaultHandler
    {
    	private HashMap<String, ReceiptInfo> returnReceipt;
		private ReceiptInfo receiptInfo;
		private String contents; 
		
		/**
		 * Class constructor.
		 */
		public saxCounter(){
			returnReceipt = new HashMap<String, ReceiptInfo>();
			
		}
		/**
		 * Indication of first element of XML file
		 */
		public void startElement( String sname, String qname)
		throws SAXException 
		{
			String ename = sname; 
			if ("".equals(ename))
				ename = qname; 
			if (ename.equals("ReturnReceipt")) 
			{ 
				receiptInfo = new ReceiptInfo();
			}			
		}
		/**
		 * All elements preceding first element in XML file
		 */
		public void endElement(String sName,String qName)
		throws SAXException {
			String eName = sName; 
			if ("".equals(eName))
				eName = qName; 
			if (eName.equals("ReturnReceipt")) 
			{ 
				returnReceipt.put(receiptInfo.uid, receiptInfo);
			}// when the parser encounters </returnreceipt>,add the receiptInfo to hashmap
			if (eName.equals("uid")) 
			{ 
				receiptInfo.uid = contents;
			}// when the parser encounters </uid>,record uid
			if (eName.equals("description")) 
			{ 
				receiptInfo.description = contents;
			}	// when the parser encounters </description>,record description
			if (eName.equals("subTotal")) 
			{ 
				receiptInfo.subTotal = contents;
			}// when the parser encounters </subTotal>,record subTotal
			if (eName.equals("gstTax")) 
			{ 
				receiptInfo.gstTax = contents;
			}// when the parser encounters </gstTax>,record gstTax
			if (eName.equals("refund")) 
			{ 
				receiptInfo.refund = contents;
			}// when the parser encounters </refund>,record refund
			
		}
		/**
         * Method for Content formatting
         */
		public void characters(char[] buf, int offset, int len)throws SAXException 
		{
			contents = new String(buf, offset, len).trim();
		}
		
		}
 }

  
